<?php

namespace App\Http\Controllers\Cruise;

use App\Enums\Cruise\ErrCode;
use App\Exceptions\Custom\ResponseHttpException;
use App\Http\Controllers\BaseController;
use App\Http\Middleware\OpenShop\FeishuWebAuth;
use App\Http\Middleware\OpenShop\UserPermissionAuth;
use App\Library\Rms\RmsShopApi;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Service\Cruise\Check\CruiseOrderService;
use App\Service\Cruise\Mission\CheckInputService;
use App\Service\Cruise\Mission\CruiseMissionService;
use App\Service\Cruise\Mission\CruiseOrderInputService;
use App\Service\Cruise\Shop\CruiseShopService;
use App\Service\OpenShop\Feishu\PermissionService;
use App\Service\OpenShop\SiteLocation\AuthService;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class CruiseController extends BaseController
{

    /**
     * 列表统计数据
     * @param Request $request
     * @return JsonResponse
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function listsCount(Request $request): JsonResponse
    {
        $authInfo = AuthService::getRmsUserInfo($request);
        $type     = $request->get('type', CruiseOrderModel::TYPE_NEW_SHOP_HELP);  // 根据类型去区分新店帮扶还是稽核...
        $level    = $request->get('level', 2);
        $cityCode = $request->get('cityCode', 0);
        $platformName = $request->header('platformname', '');    //不同的小程序
        //通用模块判断
        $category = $request->header('category', 0);    //category = 5 工厂稽核
        if ($category != 0) {
            $type = $category;
        }

        if ($type == CruiseOrderModel::TYPE_NEW_SHOP_HELP) {
            $scope           = PermissionService::dataPermission(PermissionService::CRUISE_CRUISE_LISTS, [], UserPermissionAuth::MODULE_CRUISE);
            $orderPermission = (new PermissionService)->getOrderPermissionDataOrder($scope, $authInfo['userId']);
        } else {
            $orderPermission = (new PermissionService())->dataCheckPermission(PermissionService::CRUISE_CHECK_TASK_LISTS, [], UserPermissionAuth::MODULE_CRUISE, PermissionService::ORIGIN_TASK, $type);
        }
        return $this->success(CruiseMissionService::getMissionCount($orderPermission, $type, $level, $cityCode, $platformName));
    }


    /**
     * 获得代办列表
     * @param Request $request
     * @return JsonResponse
     * @throws GuzzleException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function lists(Request $request): JsonResponse
    {
        $status   = $request->get('status', 0);
        $pageNum  = (int)$request->get('pageNum', 1);
        $type     = (int)$request->get('type', CruiseOrderModel::TYPE_NEW_SHOP_HELP);
        $pageSize = (int)$request->get('pageSize', 10);
        $search   = (string)$request->get('search');   //店铺编号  加盟商姓名
        $cityCode = $request->get('cityCode', 0);
        $platformName = $request->header('platformname', '');    //不同的小程序

        //通用模块判断
        $category = $request->header('category', 0);    //category = 5 工厂稽核
        if ($category != 0) {
            $type = $category;
        }
        $authInfo = AuthService::getRmsUserInfo($request);
        if ($type == CruiseOrderModel::TYPE_NEW_SHOP_HELP) {
            $scope           = PermissionService::dataPermission('', [], UserPermissionAuth::MODULE_CRUISE);
            $orderPermission = (new PermissionService)->getOrderPermissionDataOrder($scope, $authInfo['userId']);
        } else {
            $orderPermission = (new PermissionService())->dataCheckPermission(PermissionService::CRUISE_CHECK_TASK_LISTS, [], UserPermissionAuth::MODULE_CRUISE, PermissionService::ORIGIN_TASK, $type, $platformName);
        }
        $name        = '';
        $shopCode    = '';
        $companyName = '';
        if ($type == CruiseTemplateModel::TYPE_5) {
            $companyName = $search;
        } else {
            if (mb_strlen($search)) {
                if (is_numeric($search)) {
                    $shopCode = $search;
                } else {
                    $name = $search;
                }
            }
        }
        return $this->success(CruiseMissionService::getMissionList($status, $pageNum, $pageSize, $name, $shopCode, $cityCode, $orderPermission, $type, $companyName, '', '', '', '', 0, 0, [], $platformName));
    }

    //todo 任务列表

    /**
     * @throws ContainerExceptionInterface
     * @throws GuzzleException
     * @throws NotFoundExceptionInterface
     */
    public function cruiseList(Request $request): JsonResponse
    {
        $status    = $request->get('status', 0);
        $pageNum   = (int)$request->get('pageNum', 1);
        $type      = (int)$request->get('type', CruiseOrderModel::TYPE_CHECK);
        $taskName  = $request->get('taskName', '');
        $pageSize  = (int)$request->get('pageSize', 10);
        $search    = (string)$request->get('search');   //店铺编号  加盟商姓名
        $cityCode  = (int)$request->get('cityCode', 0);
        $shopIds   = $request->get('shopIds', '');
        $startDate = $request->get('startDate', '');
        $endDate   = $request->get('endDate', '');
        $inspector = (int)$request->get('inspector', 0);
        $handle    = (int)$request->get('handle', 0);
        $cruiseCheckCompanyIds = (string)$request->get('cruiseCheckCompanyIds');
        $cruiseCheckCompanyIds = $cruiseCheckCompanyIds ? explode(',', $cruiseCheckCompanyIds) : [];

        $name      = '';
        $shopCode  = '';
        $companyName  = '';
        if (mb_strlen($search)) {
            if (is_numeric($search)) {
                $shopCode = $search;
            } else {
                $name = $search;
            }
        }

        $orderPermission = (new PermissionService())->dataCheckPermission(PermissionService::CRUISE_CHECK_TASK_LISTS, [], UserPermissionAuth::MODULE_CRUISE, PermissionService::ORIGIN_TASK, $type);
        return $this->success(CruiseMissionService::getMissionList($status, $pageNum, $pageSize, $name, $shopCode, $cityCode, $orderPermission, $type, $companyName, $taskName, $shopIds, $startDate, $endDate, $inspector, $handle, $cruiseCheckCompanyIds));
    }

    /**
     * 获得代办任务详情
     * @param Request $request
     * @param $id
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function info(Request $request, $id): JsonResponse
    {
        $platformName = (string)$request->header('platformName');

        $authInfo = ['userId' => getRmsUserId()];

        return $this->success(CruiseMissionService::getMissionInfo($authInfo, $id, $platformName));
    }

    //todo 任务列表详情
    public function cruiseDetail(Request $request, $id): JsonResponse
    {
        $authInfo = ['userId' => FeishuWebAuth::$userId];
        return $this->success(CruiseMissionService::getMissionInfo($authInfo, $id));
    }


    /**
     * 门店列表
     * @param Request $request
     * @return JsonResponse
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function shopList(Request $request): JsonResponse
    {
        $orderBy       = (int)$request->get('orderBy', 1);
        $status        = (int)$request->get('status', -1);
        $pageNum       = (int)$request->get('pageNum', 1);
        $pageSize      = (int)$request->get('pageSize', 10);
        $search        = (string)$request->get('search');   //店铺编号,加盟商姓名,门店名称
        $cityCode      = (int)$request->get('cityCode', 0);
        $level         = (int)$request->get('level', 2);
        $orderRatioMin = (int)$request->get('ratioMin', 0);
        $orderRatioMax = (int)$request->get('ratioMax', 0);
        $shopGrade     = (int)$request->get('shopGrade', 0);
        $arriveDays    = (int)$request->get('arriveDays', 0);
        $type          = (int)$request->get('type', CruiseOrderModel::TYPE_NEW_SHOP_HELP); //权限控制
        $authInfo      = AuthService::getRmsUserInfo($request);
        $name          = '';
        $shopCode      = '';
        if (mb_strlen($search)) {
            if (is_numeric($search)) {
                $shopCode = $search;
            } else {
                $name = $search;
            }
        }
        if ($type == CruiseOrderModel::TYPE_NEW_SHOP_HELP) {
            $scope           = PermissionService::dataPermission(PermissionService::CRUISE_CRUISE_LISTS, [], UserPermissionAuth::MODULE_CRUISE);
            $orderPermission = (new PermissionService)->getOrderPermissionDataOrder($scope, $authInfo['userId']);
        } else {
            $orderPermission = (new PermissionService())->dataCheckPermission(PermissionService::CRUISE_CHECK_TASK_LISTS, [], UserPermissionAuth::MODULE_CRUISE, PermissionService::ORIGIN_SHOP, $type);
        }
        return $this->success(CruiseShopService::list($orderBy, $pageNum, $pageSize, $name, $shopCode, $cityCode,
            $level, $status, $orderPermission, $orderRatioMin, $orderRatioMax, $shopGrade, $arriveDays));
    }


    /**
     * 获取门店详情
     * @param Request $request
     * @param $shopId
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function shopDetail(Request $request, $shopId): JsonResponse
    {
        $type = $request->get('type', CruiseOrderModel::TYPE_NEW_SHOP_HELP);
        return $this->success(CruiseShopService::detail($shopId, $type));
    }

    public function inputsInfo(Request $request)
    {
        $shopId  = (int)$request->header('shopId');
        $orderNo = (string)$request->get('orderNo');

        // 不同路由获取
        $action     = request()->route()->getAction();
        $middleware = attributeGet($action, "middleware", []);
        if (in_array('kmsAuth:kmsApi', $middleware)) {
            $userId = request()->user()->rmsUserId;
        } else {
            $userId = getRmsUserId();
        }
        if (!$shopId && !$orderNo) {
            return $this->fail(1, 'shopId不能为空');
        }
        $cruiseOrderModel = CruiseOrderModel::getOrder($shopId, CruiseOrderModel::TYPE_NEW_SHOP_HELP, $orderNo);
        $data             = (new CruiseOrderInputService($cruiseOrderModel))->getInputObjectFill($userId, true);

        return $this->success($data);
    }

    public function inputsInfoWeb(Request $request)
    {
        $orderNo = (string)$request->get('orderNo');

        try {
            $cruiseOrderModel = CruiseOrderModel::getOrder(0, CruiseOrderModel::TYPE_NEW_SHOP_HELP, $orderNo);
        } catch (ResponseHttpException $e) {
            $content = json_decode($e->getResponse()->getContent(), true);
            if ($content['code'] == ErrCode::CODE_ERR_NO_HELP_CRUISE) {
                return $this->fail(ErrCode::CODE_ERR_NO_HELP_CRUISE, '');
            }

            return $this->fail($content['code'], $content['msg']);
        }
        $data = (new CruiseOrderInputService($cruiseOrderModel))->getInputObjectFill(0, false);

        return $this->success($data);
    }

    public function inputsUpdate(Request $request)
    {
        $shopId  = (int)$request->header('shopId');
        $field   = (string)$request->get('field');
        $value   = $request->get('value');
        $userId  = getRmsUserId();
        $orderNo = (string)$request->get('orderNo', '');

        $request->merge(['shopId' => $request->header('shopId')]);

        $this->validate($request, [
            'shopId' => 'required|integer',
            'field'  => 'required|string',
        ]);

        (new CruiseOrderInputService(
            CruiseOrderModel::getOrder(
                $shopId, CruiseOrderModel::TYPE_NEW_SHOP_HELP, $orderNo
            )
        ))->saveUserContentJson($userId, $field, $value);

        return $this->success();
    }

    public function inputsSubmit(Request $request)
    {
        $shopId  = (int)$request->header('shopId');
        $orderNo = (string)$request->get('orderNo', '');
        $userId  = getRmsUserId();

        (new CruiseOrderInputService(
            CruiseOrderModel::getOrder(
                $shopId, CruiseOrderModel::TYPE_NEW_SHOP_HELP, $orderNo
            )
        ))->submitOrder($userId);

        return $this->success();
    }

    public function audit(Request $request)
    {
        $shopId       = (int)$request->header('shopId');
        $orderNo      = (string)$request->get('orderNo', '');
        $auditStatus  = $request->get('auditStatus');
        $auditContent = $request->get('auditContent');
        $userInfo     = getRmsUserInfoByAuth();
        $userId       = $userInfo->id;
        $userName     = $userInfo->username;

        (new CruiseOrderInputService(
            CruiseOrderModel::getOrder(
                $shopId, CruiseOrderModel::TYPE_NEW_SHOP_HELP, $orderNo
            )
        ))->audit(
            $userId, $userName, $auditStatus,
            $auditContent
        );

        return $this->success();
    }

    public function getBusinessData(Request $request)
    {
        $shopId    = (int)($request->header('shopId') ? $request->get('shopId') : 0);
        $startDate = (string)$request->get('startDate');
        $day       = (int)$request->get('day', 3);
        $shopCode  = (string)$request->get('shopCode');

        if ($shopCode) {
            $mainProcessId = (int)OpenShopSignOrderModel::query()->where('shopCode', $shopCode)->value('mainProcessId');
            $shopId        = (int)OpenShopMainProcessModel::query()->where('id', $mainProcessId)->value('shopId');
        }

        $businessData = (new RmsShopApi())->getBusinessData($shopId, $startDate, $day);

        return $this->success($businessData['data']);
    }

    /**
     * 订货指标
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function shopOrderTarget(Request $request)
    {
        $this->validate($request, [
            'month'  => 'required',
            'shopId' => 'required|numeric'
        ]);
        return $this->success(CruiseShopService::orderTarget($request->month, $request->shopId));
    }

    public function startBusinessStatus(Request $request)
    {
        $this->validate($request, [
            'cityCode' => 'numeric'
        ]);
        $type = $request->get('type', CruiseOrderModel::TYPE_NEW_SHOP_HELP);
        $authInfo = AuthService::getRmsUserInfo($request);
        if ($type == CruiseOrderModel::TYPE_NEW_SHOP_HELP) {
            $scope    = PermissionService::dataPermission(PermissionService::CRUISE_CRUISE_LISTS, [], UserPermissionAuth::MODULE_CRUISE);
            $orderPermission = (new PermissionService)->getOrderPermissionDataOrder($scope, $authInfo['userId']);
        } else {
            $orderPermission = (new PermissionService())->dataCheckPermission(PermissionService::CRUISE_CHECK_TASK_LISTS, [], UserPermissionAuth::MODULE_CRUISE, PermissionService::ORIGIN_SHOP, $type);
        }
        return $this->success(CruiseShopService::getOpenBusinessCount($orderPermission, $request->cityCode));
    }

    /**
     * 更新稽核人员照片
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function updateCheckUserPhone(Request $request): JsonResponse
    {
        $this->validate($request, [
            'photo' => 'string|required'
        ]);
        CruiseOrderService::updateCheckUserPhone(AuthService::getRmsUserInfo($request), $request->photo);
        return $this->success();
    }

    /**
     * 稽核小程序获取稽核名片
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException|Exception
     */
    public function getCheckUserInfo(Request $request): JsonResponse
    {
        return $this->success(CruiseOrderService::getCheckUserInfo(AuthService::getRmsUserInfo($request)));
    }

    /**
     * 督导打分
     * @param Request $request
     * @param int $id CruiseOrderId
     * @return JsonResponse
     * @throws ValidationException
     */
    public function superviseGrade(Request $request, int $id): JsonResponse
    {
        $this->validate($request, [
            'params.*.field' => 'required|string',
            'params.*.score' => 'required|int',
            'score'          => 'required|int'
        ]);
        CruiseOrderService::superviseScore($request->params, $id, FeishuWebAuth::$userId, $request->score);
        return $this->success();
    }

    /**
     * 督导驳回
     * @param Request $request
     * @param int $id CruiseOrderId
     * @return JsonResponse
     */
    public function superviseReject(Request $request, int $id): JsonResponse
    {
        $content = $request->post('content', '');
        (new CheckInputService($id, FeishuWebAuth::$userId))->kfReject($content);

        return $this->success();
    }

    // 稽核小程序tab权限
    public function tabPermission(Request $request)
    {
        $appId = (string)$request->get('appId');

        $this->validate($request, [
            'appId' => 'required|string',
        ]);

        $permissionLists = getRmsUserPermissionList([], UserPermissionAuth::MODULE_CRUISE);

        $tabs = collect(CruiseOrderService::tabPermission(getRmsUserId(), $permissionLists, $appId))
            ->unique()
            ->map(function ($item) {
                return [
                    'tab'  => $item,
                    'text' => CruiseOrderService::CRUISE_TAB_TEXT[$item] ?? '',
                ];
            })->sortBy('tab')->values()->toArray();

        return $this->success($tabs);
    }

    /**
     * 可转交的人员列表
     * @param Request $request
     */
    public function transferUsers(Request $request)
    {
        $this->validate($request, [
            'cruiseOrderIds'   => 'required|string',
        ]);

        $cruiseOrderIds = explode(',', $request->get('cruiseOrderIds'));

        return $this->success(CruiseOrderService::transferUsers($cruiseOrderIds));
    }

    /**
     * 任务转交
     * @param Request $request
     */
    public function transfer(Request $request)
    {
        $this->validate($request, [
            'cruiseOrderIds'   => 'required|array',
            'targetUserId'     => 'required|integer',
        ]);

        $do = CruiseOrderService::transfer((array)$request->post('cruiseOrderIds'), (int)$request->post('targetUserId'));
        if ($do['code'] > 0) {
            return $this->fail($do['code'], $do['msg'], $do['data']);
        }

        return $this->success();
    }
}
